<template>
  <el-dialog width="60%" :title="dialogTitle" v-model="dialogVisible" modal @close="closeDialog" draggable
    :close-on-click-modal="false" :append-to-body="true">
    <el-form class="dialog-form" :model="formData" ref="readerForm" label-position="right" label-width="100px"
      size="medium" @submit.native.prevent>
      <el-form-item label="选择设备:">
        <el-radio-group v-model="activeName">
          <el-radio label="reader">读写器</el-radio>
          <el-radio label="printer">打印机</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item v-if="activeName === 'reader'" label="读写器:" prop="readerDeviceId">
        <el-select v-model="formData.readerDeviceId" placeholder="请选择读写器" class="full-width-input" clearable
          @change="changeReader">
          <el-option v-for="(item, index) in readerOptions" :key="index" :label="item.label" :value="item.value"
            :disabled="item.disabled">
            <span style="float: left">{{ item.label }}</span>
            <span style="float: right; color: #8492a6; font-size: 13px; margin-left: 10px">{{
              item.type === '0' ? '超高频' : '高频'
              }}</span></el-option>
        </el-select>
      </el-form-item>
      <el-form-item v-if="activeName === 'reader'" label="读写器状态:" prop="readerState">
        <el-tag :type="formData.readerState === '正常' ? 'success' : 'danger'">{{
          formData.readerState
          }}</el-tag>
        <el-button type="primary" size="mini" style="margin-left: 10px;" @click="reconnect('reader')">重新连接</el-button>
      </el-form-item>
      <el-row v-if="activeName === 'printer'">
        <el-col :span="20">
          <el-form-item label="打印机:" prop="printerDeviceId">
            <el-select v-model="formData.printerDeviceId" placeholder="请选择打印机" class="full-width-input" clearable>
              <el-option v-for="(item, index) in printerOptions" :key="index" :label="item.deviceName"
                :value="item.deviceId" :disabled="item.disabledFlag != 0" @click.native="changePrinter(item)">
              </el-option>
            </el-select>
          </el-form-item>
          <el-row>
            <el-col :span="12">
              <el-form-item label="打印机状态:" prop="printerState">
                <el-tag :type="formData.printerState ? 'success' : 'danger'">{{
                  formData.printerState ? '正常' : '离线'
                  }}</el-tag>
                <el-button type="primary" size="mini" style="margin-left: 10px;"
                  @click="reconnect('printer')">重新连接</el-button>
              </el-form-item>

            </el-col>
            <el-col :span="12">
              <el-form-item label="模版设置:">
                <el-radio-group v-model="formData.templateSet">
                  <el-radio :label="0">横版</el-radio>
                  <el-radio :label="1">竖版</el-radio>
                  <el-radio :label="2">方正版</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
          </el-row>
        </el-col>
        <el-col :span="4">
          <el-button style="float: right; width: 90px; height: 90px" type="primary" @click="printeTable">打印</el-button>
        </el-col>
      </el-row>
    </el-form>

    <el-table :data="tableData" border style="width: 100%" height="30vh" :row-class-name="getRowStyle">
      <el-table-column v-for="item of tableProps" :key="item.props" :prop="item.prop" :label="item.title"
        :width="item.width" show-overflow-tooltip>
      </el-table-column>
      <el-table-column label="操作" min-width="60">
        <template slot-scope="{ row }">
          <el-button v-if="activeName === 'reader' && type === 'register'" link size="mini"
            @click="getRfid(row)">读卡</el-button>
          <el-button v-if="activeName === 'reader' && type === 'replace'" link size="mini"
            @click="replaceLabel(row)">更换</el-button>
          <el-popconfirm class="button10Left" title="确定要删除吗？" @confirm="() => handleDel(row)">
            <el-button slot="reference" icon="el-icon-delete" link size="mini" class="danger_button">删除</el-button>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
    <div slot="footer" class="dialog-footer">
      <el-button v-if="activeName === 'reader' && type === 'replace'" @click="closeDialog" size="mini">关 闭</el-button>
      <el-button v-else @click="closeDialog" size="mini">取 消</el-button>
      <el-button v-if="activeName === 'printer' && type === 'replace'" type="primary" @click="submitForm" size="mini">更
        换</el-button>
      <el-button v-if="type === 'register'" type="primary" @click="register" size="mini">注 册</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { dropDown, getInfo } from '@/api/bas/rfidReader'
import {
  dropDown as dropDownPrinter,
  getInfo as getPrinterInfo,
  deviceRfidPrinterlist,
} from '@/api/bas/printer'
import axios from 'axios'
import { ElNotification } from 'element-plus'
import { queryByRfid } from '@/api/rfid/label'
import {
  archiveReplace,
  archiveBatchReplace,
  archiveBatchRegister,
  boxReplace,
  boxBatchReplace,
  boxBatchRegister,
  shelfBatchReplace,
  shelfBatchRegister,
} from '@/api/rfid/labelReplace'
import { initWebSocket, closeWebSocket, printTableData } from '@/utils/prints'
import createRrfidNumber from '@/utils/CreateRrfidNumber'

export default {
  name: 'labelBatchReplaceDialog',
  props: {
    field: {
      type: Object,
      default: () => {
        return {}
      },
    },
  },
  data() {
    return {
      type: '',
      labelType: '',
      activeName: 'reader',
      dialogTitle: '',
      dialogVisible: false,
      formData: {
        readerDeviceId: '',
        readerState: '未选择读写器',
        printerState: false,
        printerDeviceId: '',
        templateSet: 0,
      },
      tableData: [],
      originalTableData: [],
      tableProps: [],
      readerInfo: {},
      readerOptions: [],
    }
  },
  watch: {
    field(newv) {
      this.formData.templateSet = newv.templateStyle
    },
  },
  computed: {},
  mounted() {
    // 复制原始数据
  },
  methods: {
    reconnect(flag) {
      if (flag === 'reader') {
        this.changeReader(this.formData.readerDeviceId)
      } else {
        this.changePrinter(this.formData.printerDeviceId)
      }
    },
    getRowStyle({ row, rowIndex }) {
      if (row.isPrint === 1) {
        return 'success-row'
      }
      return ''
    },
    async printeTable() {
      for (const [index, item] of this.tableData.entries()) {
        if (this.dialogTitle == '标签注册') {
          item.rfid = createRrfidNumber(1) // 添加rfid属性
          item.isPrint = 1
        } else if (this.dialogTitle == '标签更换') {
          if (item.rfid == '' || item.rfid == null) {
            item.rfid = createRrfidNumber(1) // 添加rfid属性
            item.isPrint = 1
          }
        }

        // this.getRowStyle(row)
        if (this.field.labelType == 2) {
          // 针对层架模版的数据不一致的原因，在此处自定义数据用于传值打印
          let fields = [
            {
              fieldName: 'position_name',
              fieldTitle: '库位名称',
              dataType: 'String',
              fontFamily: '楷体',
              fontSize: '16',
              createBy: 'admin',
              updateBy: 'admin',
            },
          ]
          printTableData(item, this.formData.templateSet, fields)
        } else {
          // 这里可以执行连接成功后的操作 对档案和档案盒的数据
          printTableData(item, this.formData.templateSet, this.field.fields)
        }
        await new Promise((resolve) => setTimeout(resolve, 2000)) // 暂停1秒
      }
    },
    changePrinter(value) {
      initWebSocket(value.deviceIp)
        .then((ws) => {
          // 这里可以执行连接成功后的操作
          if (ws) {
            this.formData.printerState = true
          }
        })
        .catch((error) => {
          console.error('WebSocket连接失败或不支持:', error.message)
          // 这里可以处理连接失败的情况
        })
      // websocketonmessage()
      // if (initWebSocket()) {
      // } else {
      // }

      // getPrinterInfo(value)
      //   .then((res) => {
      //     if (res.data.code === 200) {
      //       this.printerInfo = res.data.data
      //       // 连接websocket
      //     } else {
      //       this.$message.error(res.data.message)
      //     }
      //   })
      //   .catch((err) => {
      //     this.$message.error(err)
      //   })
    },
    // 获取打印机的列表
    getPrinter() {
      deviceRfidPrinterlist()
        .then((res) => {
          if (res.data.code === 200) {
            this.printerOptions = res.data.data
          } else {
            this.$message.error(res.data.message)
          }
        })
        .catch((err) => {
          this.$message.error(err)
        })
    },
    handleClick(tab, event) {
      if (tab.name === 'reader') {
        this.activeName = 'reader'
      } else if (tab.name === 'printer') {
        this.activeName = 'printer'
      }
    },
    getReader() {
      dropDown()
        .then((res) => {
          if (res.data.code === 200) {
            this.readerOptions = res.data.data
          } else {
            this.$message.error(res.data.message)
          }
        })
        .catch((err) => {
          this.$message.error(err)
        })
    },
    // 选择读写器的逻辑
    changeReader(value) {
      getInfo(value)
        .then((res) => {
          if (res.data.code === 200) {
            this.readerInfo = res.data.data
            this.takeOn(res.data.data.deviceIp, res.data.data.devicePort)
          } else {
            this.$message.error(res.data.message)
          }
        })
        .catch((err) => {
          this.$message.error(err)
        })
    },
    add(record, type, labelType) {
      this.type = type
      this.labelType = labelType
      // 在此处调用打印机和读写器的列表
      this.getReader()
      this.getPrinter()

      if (type === 'register') {
        this.dialogTitle = '标签注册'
      } else if (type === 'replace') {
        this.dialogTitle = '标签更换'
      }
      if (labelType === 'box') {
        this.tableProps = [
          { title: '盒号', prop: 'boxNo', width: '', checked: true },
          { title: '盒名', prop: 'boxName', width: '', checked: true },
          { title: 'RFID', prop: 'rfid', width: '', checked: true },
          { title: '盒宽(CM)', prop: 'boxWidth', width: '', checked: true },
        ]
        this.tableData = JSON.parse(JSON.stringify(record)).map((item) => {
          return {
            ...item,
            isPrint: 0,
          }
        })
      } else if (labelType === 'archive') {
        this.tableProps = [
          { title: '档号', prop: 'archiveNo', width: '', checked: true },
          { title: '题名', prop: 'archiveName', width: '', checked: true },
          { title: 'RFID', prop: 'rfid', width: '', checked: true },
          { title: '页数', prop: 'pageNo', width: '', checked: true },
        ]
        this.tableData = JSON.parse(JSON.stringify(record)).map((item) => {
          return {
            ...item,
            isPrint: 0,
          }
        })
      } else if (labelType === 'shelf') {
        this.tableProps = [
          { title: '库位名称', prop: 'positionName', width: '', checked: true },
          { title: '库位编号', prop: 'positionId', width: '', checked: true },
          { title: 'RFID', prop: 'rfid', width: '', checked: true },
        ]
        this.tableData = JSON.parse(JSON.stringify(record)).map((item) => {
          return {
            ...item,
            labelId: item.positionId,
            isPrint: 0,
          }
        })
      }

      this.dialogVisible = true
    },
    // 开启读写器的操作
    takeOn(ip, port) {
      const that = this
      let url = `http://${ip}:${port}/takeon`
      axios
        .get(url, { timeout: 10000 })
        .then((res) => {
          if (res.data.search('ok') !== -1) {
            that.formData.readerState = '正常'
          } else {
            that.formData.readerState = '离线'
          }
        })
        .catch((error) => {
          that.formData.readerState = '离线'
          this.$message.warning('连接失败')
        })
    },

    // 从读写器获取rfid号
    getRfid(row) {
      const that = this
      if (that.formData.readerState === '正常') {
        // 进行开启读写器
        this.takeOn(this.readerInfo.deviceIp, this.readerInfo.devicePort)
        // 开始读取
        // 开始读取
        this.getRfidData((rfidId) => {
          that.formData.rfid = rfidId
          that.tableData.forEach((item, index) => {
            if (item.labelId === row.labelId) {
              item.rfid = rfidId
              // that.tableRowClassName({item, index})
            }
          })
        })
      } else if (that.formData.readerState === '离线') {

        this.$message.warning('读写器离线')
      } else {
        this.$message.warning('请选择读写器')


      }
    },
    tableRowClassName({ row, rowIndex }) {
      this.tableData.map((x) => {
        x.rfid == row.rfid
      })
      // if (flag && row.rfid) {
      //   return 'success-row'
      // }
    },
    // 写卡的操作
    setRfid(row) {
      const that = this
      let url = `http://${that.readerInfo.deviceIp}:${that.readerInfo.devicePort}/setrfid/${row.rfid}`

      axios
        .get(url, { timeout: 1000 })
        .then((res) => {
          if (res.data.search('ok') !== -1) {
            this.replace(row)
          } else {
            ElNotification({
              message: '标签更换失败,读写器只能放置一个标签',
              type: 'warning',
            })
          }
        })
        .catch((error) => {
          this.$message.warning('连接失败')
        })
    },
    takeOff() {
      const that = this

      let url = `http://${that.readerInfo.deviceIp}:${that.readerInfo.devicePort}/takeoff`
      axios
        .get(url, { timeout: 1000 })
        .then((res) => {
          if (res.data.search('ok') !== -1) {
            // this.$message.warning('关闭连接')
          } else {
            ElNotification({
              message: '读写器关闭失败',
              type: 'warning',
            })
          }
        })
        .catch((error) => {
          this.$message.warning('连接失败')
        })
    },
    getRfidData(callback, retryCount = 0) {
      const maxRetries = 5 // 最大重试次数
      const url = `http://${this.readerInfo.deviceIp}:${this.readerInfo.devicePort}/getrfid/?deviceType=${this.readerInfo.deviceType}`
      axios
        .get(url, { timeout: 1000 })
        .then((res) => {
          const rfidData = eval('(' + res.data + ')').result

          if (rfidData.length === 0) {
            // 没有获取到数据
            if (retryCount < maxRetries) {
              // 重试获取数据
              setTimeout(() => {
                this.getRfidData(callback, retryCount + 1) // 重试获取数据
              }, 1000) // 1秒后重试
            } else {
              // 达到最大重试次数
              ElNotification({
                message: '未能获取到标签，请检查设备',
                type: 'warning',
              })
              this.takeOff()
            }
          } else if (rfidData.length > 1) {
            ElNotification({
              message: '只能放置一个标签',
              type: 'warning',
            })
          } else {
            // 只有一个标签时，获取其ID
            const rfidId = rfidData[0].ID

            // 查询数据库是否有使用此标签
            callback(rfidId)
          }
        })
        .catch((error) => {
          this.$message.warning('连接失败')
        })
    },
    replaceLabel(row) {
      /**
       * 逻辑
       * 1。点击更换的时候先进行开启读写器
       * 2.从读写器中获取到这个号的时候进行查询数据库中有无使用这个标签和进行关闭操作
       * 3.如果标签使用过，则提示标签已被使用，如果没使用过，则进行写入操作
       */
      if (this.formData.readerState === '正常') {
        // 进行开启读写器
        this.takeOn(this.readerInfo.deviceIp, this.readerInfo.devicePort)
        // 开始读取
        this.getRfidData((rfidId) => {
          // 查询数据库是否有使用此标签
          queryByRfid(rfidId).then((res) => {
            if (res.data.code === 200) {
              this.takeOff() // 关闭读写器
              this.setRfid(row) // 设置RFID
            } else {
              ElNotification({
                message: res.data.message,
                type: 'warning',
              })
            }
          })
          this.takeOff()
        })
      } else if (this.formData.readerState === '离线') {
        ElNotification({
          message: '读写器离线',
          type: 'warning',
        })
      } else {
        ElNotification({
          message: '请选择读写器',
          type: 'warning',
        })
      }
    },
    replace(row) {
      const param = {
        labelId: row.labelId,
        oldRfid: row.rfid,
        newRfid: row.rfid,
      }
      if (this.labelType === 'archive') {
        archiveReplace(param)
          .then((res) => {
            if (res.data.code === 200) {
              this.$message.success('更换成功')
              this.tableData = this.tableData.filter((item) => item.labelId !== row.labelId)
              if (this.tableData.length === 0) {
                this.$emit('ok')
              }
            } else {
              this.$message.warning(res.data.message)
            }
          })
          .catch((err) => {
            this.$message.error(err)
          })
      } else if (this.labelType === 'box') {
        boxReplace(param)
          .then((res) => {
            if (res.data.code === 200) {
              this.$message.success('更换成功')
              this.$emit('ok')
            } else {
              this.$message.warning(res.data.message)
            }
          })
          .catch((err) => {
            this.$message.error(err)
          })
      } else if (this.labelType === 'shelf') {
        shelfBatchReplace([param])
          .then((res) => {
            if (res.data.code === 200) {
              this.$message.success('更换成功')
              this.$emit('ok')
            } else {
              this.$message.warning(res.data.message)
            }
          })
          .catch((err) => {
            this.$message.error(err)
          })
      }
    },
    handleDel(row) {
      this.tableData = this.tableData.filter((item) => item.labelId !== row.labelId)
    },
    register() {
      let table = this.tableData.map((item, index) => {
        return {
          ...item,
          newRfid: item.rfid,
        }
      })
      // 如果tableData中存在新的rfid为''的
      if (this.tableData.filter((item) => item.newRfid === '').length > 0) {
        this.$message.warning('存在未读卡的标签')
        return
      }
      this.$confirm(
        `请确认标签${this.activeName == 'reader' ? '读卡' : '打印'}完成, 是否继续?`,
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
        }
      ).then(() => {
        if (this.labelType === 'archive') {
          archiveBatchRegister(table)
            .then((res) => {
              if (res.data.code === 200) {
                this.$message.success('批量注册成功')
                this.closeDialog()
                this.$emit('ok')
              } else {
                this.$message.warning(res.data.message)
              }
            })
            .catch((err) => {
              this.$message.error(err)
            })
        } else if (this.labelType === 'box') {
          boxBatchRegister(table)
            .then((res) => {
              if (res.data.code === 200) {
                this.$message.success('批量注册成功')
                this.closeDialog()
                this.$emit('ok')
              } else {
                this.$message.warning(res.data.message)
              }
            })
            .catch((err) => {
              this.$message.error(err)
            })
        } else if (this.labelType === 'shelf') {
          shelfBatchRegister(table)
            .then((res) => {
              if (res.data.code === 200) {
                this.$message.success('批量注册成功')
                this.closeDialog()
                this.$emit('ok')
              } else {
                this.$message.warning(res.data.message)
              }
            })
            .catch((err) => {
              this.$message.error(err)
            })
        }
      })
    },
    submitForm() {
      // 判断表格中是否还有数据
      if (this.tableData.length === 0) {
        this.$message.warning('列表不能为空')
        return
      }
      // 将表格中的rfid值拿出来
      const rfidArr = this.tableData.map((item) => item.newRfid)
      if (rfidArr.includes('') || rfidArr.includes(null)) {
        this.$message.warning('列表中新RFID不能为空')
        return
      }
      // 判断列表中的rfid是否有重复的
      if (
        this.tableData.some((item, index, arr) => {
          return arr.indexOf(item) !== index
        })
      ) {
        this.$message.warning('列表中新RFID不能重复')
        return
      }
      this.$confirm(
        `请确认标签${this.activeName == 'reader' ? '读卡' : '打印'}完成, 是否继续?`,
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
        }
      ).then(() => {
        if (this.labelType === 'shelf') {
          shelfBatchReplace(this.tableData)
            .then((res) => {
              if (res.data.code === 200) {
                this.$message.success('批量更换成功')
                this.closeDialog()
                this.$emit('ok')
              } else {
                this.$message.warning(res.data.message)
              }
            })
            .catch((err) => {
              this.$message.error(err)
            })
        } else if (this.labelType === 'box') {
          boxBatchReplace(this.tableData)
            .then((res) => {
              if (res.data.code === 200) {
                this.$message.success('批量更换成功')
                this.closeDialog()
                this.$emit('ok')
              } else {
                this.$message.warning(res.data.message)
              }
            })
            .catch((err) => {
              this.$message.error(err)
            })
        } else if (this.labelType === 'archive') {
          archiveBatchReplace(this.tableData)
            .then((res) => {
              if (res.data.code === 200) {
                this.$message.success('批量更换成功')
                this.closeDialog()
                this.$emit('ok')
              } else {
                this.$message.warning(res.data.message)
              }
            })
            .catch((err) => {
              this.$message.error(err)
            })
        }
      })
    },
    closeDialog() {
      if (this.formData.readerState === '正常') {
        this.takeOff()
      }
      this.$refs['readerForm'].resetFields()
      this.dialogVisible = false
      // this.$refs.tabs.$destroy()
    },
  },
}
</script>

<style scoped lang="less">
.el-table .success-row {
  background: #f0f9eb !important;
}
</style>
